package JAVA300.第十一章多线程;

/**
 * 学习可重入锁-不可重入修改为可重入--建议3实现ReentrantLock
 */
public class thread_19_others_7reEntryLock2 {

    ReLock relock = new ReLock();
    public void a (){
        relock.lock();
        System.out.println(relock.getHoldCount());//1
        doSomthing();
        relock.unlock();
        System.out.println(relock.getHoldCount());//0

    }

    //不可重入锁
    public void doSomthing(){
        relock.lock();
        //
        System.out.println(relock.getHoldCount());//2
        relock.unlock();



    }


    public static void main(String[] args) {

        thread_19_others_7reEntryLock2 entry = new thread_19_others_7reEntryLock2();
        entry.a();

    }

}

class ReLock{
    //是否占用
    private boolean isLocked= false;

    //1.添加存储线程 和 计数器
    private Thread lockedBy = null;//判断调用线程是不是当前线程
    private int holdCount =0 ;



    //使用锁

    public synchronized void lock(){

        Thread nowThread = Thread.currentThread();
        //2.
        while (isLocked && lockedBy !=nowThread){
            try {
                wait();//锁被占用 等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        isLocked = true;
        lockedBy = nowThread;
        holdCount++;

    }
    //解锁
    public synchronized void unlock(){

        // 3.被自身调用 计数器减一 在计数器0时 再彻底解锁
        if (Thread.currentThread() == lockedBy){
            holdCount--;
            if (holdCount ==0){
                isLocked = false;
                notifyAll();//唤醒
                lockedBy = null;
            }

        }





    }

    public int getHoldCount() {
        return holdCount;
    }
}
